#pragma once

#include <iostream>
#include <memory>
#include <functional>
#include <sys/wait.h>
#include "Socket.hpp"

namespace TcpServerModule
{
    using namespace SocketModule;
    using namespace LogModule;
    using tcphandler_t=std::function<bool(SockPtr,InetAddr)>;

    //只负责进行IO，流式的IO，不对协议做任何处理
    class TcpServer
    {
    public:
        TcpServer(int port)
            : _listensocket(std::make_unique<TcpSocket>())
            ,_port(port)
            , _isrunning(false)
        {
        }

        void InitServer(tcphandler_t handler)
        {
            _handler=handler;
            _listensocket->BuildTcpSocketMethod(_port);
        }
        void Loop()
        {
            _isrunning=true;
            while(_isrunning)
            {
                //1.accept
                InetAddr clientaddr;
                auto sockfd=_listensocket->Accepter(&clientaddr);
                if(sockfd==nullptr) continue;

                //IO处理
                LOG(LogLevel::DEBUG)<<"get a new client,info is:"<<clientaddr.Addr();
                // sockfd->Recv();
                // sockfd->Send();

                pid_t id=fork();
                if(id==0)
                {
                    _listensocket->Close();
                    if(fork()>0) exit(0);
                    _handler(sockfd,clientaddr);
                    exit(0);

                }
                sockfd->Close();
                waitpid(id,nullptr,0);
            }
            _isrunning=false;
        }

        ~TcpServer()
        {
            _listensocket->Close();
        }

    private:
        std::unique_ptr<Socket> _listensocket;
        bool _isrunning;
        int _port;
        tcphandler_t _handler;
    };
}